package com.usdt.system.cp.handler;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * EasyExcel 自适应列宽处理器
 * 功能：
 * 1. 自动调整所有数据列宽度
 * 2. 支持中文和特殊字符
 * 3. 支持标题行自动调整
 * 4. 支持设置最大/最小宽度
 * 5. 支持合并单元格宽度自适应
 * 6. 支持设置缩放因子
 */
public class AutoColumnWidthHandler implements CellWriteHandler {
    
    // 列宽缓存（列索引 -> 最大宽度）
    private final Map<Integer, Integer> maxColumnWidthMap = new HashMap<>();
    
    // 配置参数
    private int minWidth = 1800;        // 最小列宽（单位：1/256个字符宽度）
    private int maxWidth = 150 * 256;   // 最大列宽（150个字符）
    private float scaleFactor = 1.0f;   // 宽度缩放因子
    private boolean autoTitle = true;   // 是否自动调整标题宽度
    private boolean autoData = true;    // 是否自动调整数据宽度
    
    public AutoColumnWidthHandler() {}
    
    public AutoColumnWidthHandler(float scaleFactor) {
        this.scaleFactor = scaleFactor;
    }
    
    public AutoColumnWidthHandler(int minWidth, int maxWidth) {
        this.minWidth = minWidth;
        this.maxWidth = maxWidth;
    }
    
    // 配置方法（链式调用）
    public AutoColumnWidthHandler minWidth(int minWidth) {
        this.minWidth = minWidth;
        return this;
    }
    
    public AutoColumnWidthHandler maxWidth(int maxWidth) {
        this.maxWidth = maxWidth;
        return this;
    }
    
    public AutoColumnWidthHandler scaleFactor(float scaleFactor) {
        this.scaleFactor = scaleFactor;
        return this;
    }
    
    public AutoColumnWidthHandler autoTitle(boolean autoTitle) {
        this.autoTitle = autoTitle;
        return this;
    }
    
    public AutoColumnWidthHandler autoData(boolean autoData) {
        this.autoData = autoData;
        return this;
    }

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        // 只处理数据行和标题行
        if (!autoData && !context.getHead()) return;
        if (!autoTitle && context.getHead()) return;
        
        Cell cell = context.getCell();
        Sheet sheet = context.getWriteSheetHolder().getSheet();
        int columnIndex = cell.getColumnIndex();
        
        // 获取单元格内容宽度
        int cellWidth = calculateCellWidth(cell);
        
        // 处理合并单元格
        if (cell.getSheet().getNumMergedRegions() > 0) {
            cellWidth = handleMergedCell(cell, cellWidth);
        }
        
        // 更新列最大宽度
        updateMaxWidth(columnIndex, cellWidth);
        
        // 最后一行写入完成后设置列宽
        if (isLastRow(context)) {
            setColumnWidths(sheet);
        }
    }
    
    /**
     * 计算单元格内容所需的宽度
     */
    private int calculateCellWidth(Cell cell) {
        CellType cellType = cell.getCellType();
        String text = "";
        
        switch (cellType) {
            case STRING:
                text = cell.getStringCellValue();
                break;
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    text = cell.getDateCellValue().toString();
                } else {
                    text = String.valueOf(cell.getNumericCellValue());
                }
                break;
            case BOOLEAN:
                text = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA:
                try {
                    text = cell.getStringCellValue();
                } catch (Exception e) {
                    text = cell.getCellFormula();
                }
                break;
            default:
                text = "";
        }
        
        // 特殊处理空字符串
        if (text == null || text.isEmpty()) {
            return minWidth;
        }
        
        // 计算字符串宽度（考虑中文和特殊字符）
        int width = 0;
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            // 中文字符占2个英文字符宽度
            width += (c > 127 || c == '：' || c == '；' || c == '，' || c == '（' || c == '）') ? 2 : 1;
        }
        
        // 应用缩放因子并转换为POI单位
        int scaledWidth = (int) (width * scaleFactor * 256);
        
        // 添加额外边距
        return Math.max(minWidth, scaledWidth + 512); // +2个字符边距
    }
    
    /**
     * 处理合并单元格的宽度计算
     */
    private int handleMergedCell(Cell cell, int baseWidth) {
        Sheet sheet = cell.getSheet();
        int rowIndex = cell.getRowIndex();
        int columnIndex = cell.getColumnIndex();
        
        // 检查单元格是否在合并区域内
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress region = sheet.getMergedRegion(i);
            if (region.isInRange(rowIndex, columnIndex)) {
                // 计算合并区域的总宽度
                int mergedCols = region.getLastColumn() - region.getFirstColumn() + 1;
                // 合并单元格内的文本需要分配到各列
                return baseWidth / mergedCols;
            }
        }
        return baseWidth;
    }
    
    /**
     * 更新列的最大宽度
     */
    private void updateMaxWidth(int columnIndex, int cellWidth) {
        int currentMax = maxColumnWidthMap.getOrDefault(columnIndex, minWidth);
        if (cellWidth > currentMax) {
            // 不超过最大宽度限制
            maxColumnWidthMap.put(columnIndex, Math.min(cellWidth, maxWidth));
        }
    }
    
    /**
     * 判断是否是最后一行
     */
    private boolean isLastRow(CellWriteHandlerContext context) {
        int currentRow = context.getRowIndex();
        int totalRows = context.getWriteSheetHolder().getSheet().getLastRowNum();
        return currentRow == totalRows;
    }
    
    /**
     * 设置所有列的宽度
     */
    private void setColumnWidths(Sheet sheet) {
        for (Map.Entry<Integer, Integer> entry : maxColumnWidthMap.entrySet()) {
            int columnIndex = entry.getKey();
            int columnWidth = entry.getValue();
            sheet.setColumnWidth(columnIndex, columnWidth);
        }
    }
}